package cn.waleychain.exchange.consumer.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import cn.waleychain.exchange.core.entity.TokenEntity;
import cn.waleychain.exchange.core.exec.ClientException;
import cn.waleychain.exchange.core.exec.ForbiddenException;
import cn.waleychain.exchange.core.exec.InvalidRequestException;
import cn.waleychain.exchange.core.exec.NotFoundDataException;
import cn.waleychain.exchange.core.exec.ResourceNotFoundException;
import cn.waleychain.exchange.core.logger.LoggerHelper;
import cn.waleychain.exchange.core.result.DefaultResult;
import cn.waleychain.exchange.core.result.IBaseResult;
import cn.waleychain.exchange.core.result.RetResultCode;
import cn.waleychain.exchange.core.utils.StringUtils;

public class BaseController {

	private static final Logger mLog = LoggerFactory.getLogger(BaseController.class);
	
	@Autowired
	protected HttpServletRequest request;

	protected HttpServletResponse response;
	protected HttpSession session;
	
	protected HttpHeaders headers;
	
	protected TokenEntity token;
	
	@ModelAttribute
	public void setReqAndRes(HttpServletRequest request, HttpServletResponse response, @RequestHeader HttpHeaders headers) {
		
		this.request = request;
		this.response = response;
		this.headers = headers;
		try {
			this.session = request.getSession();
			request.setCharacterEncoding("UTF-8");
			Subject subject = SecurityUtils.getSubject();
			token = (TokenEntity) subject.getPrincipals().getPrimaryPrincipal();
		} catch (Exception e) {
			;
		}
		
	}

	@ExceptionHandler(Exception.class)
	@ResponseBody
	@ResponseStatus(value = HttpStatus.OK)
    public IBaseResult exp(Exception ex) {
		
		return DefaultResult.buildFailedResult(ex.getMessage());
    }
    
	/**
	 * 参数验证异常处理
	 * @param ex
	 * @return
	 */
	@ExceptionHandler(ClientException.class)
	@ResponseBody
	@ResponseStatus(value = HttpStatus.OK)
    public IBaseResult exp(ClientException ex) {
		
		return DefaultResult.buildFailedResult(ex.getMsgCode(), ex.getMessage());
    }
	
	@ExceptionHandler(InvalidRequestException.class)
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
	@ResponseBody
    public IBaseResult handleInvalidRequestError(InvalidRequestException ex) {
		return DefaultResult.buildFailedResult(HttpStatus.BAD_REQUEST.value(), ex.getMessage());
	}

    @ExceptionHandler(ResourceNotFoundException.class)
    @ResponseStatus(value = HttpStatus.NOT_FOUND)
    @ResponseBody
    public IBaseResult handleResourceNotFoundError(ResourceNotFoundException ex) {
		return DefaultResult.buildFailedResult(HttpStatus.NOT_FOUND.value(), ex.getMessage());
    }

    @ExceptionHandler(ForbiddenException.class)
    @ResponseStatus(value = HttpStatus.FORBIDDEN)
    @ResponseBody
    public IBaseResult handleRorbiddenError(ForbiddenException ex) {
		return DefaultResult.buildFailedResult(HttpStatus.FORBIDDEN.value(), ex.getMessage());
    }

    @ExceptionHandler(RuntimeException.class)
    @ResponseStatus(value = HttpStatus.OK)
    @ResponseBody
    public IBaseResult handleUnexpectedServerError(RuntimeException ex) {

    	if (ex instanceof AuthorizationException) {
    		// 权限不足
    		return DefaultResult.buildFailedResult(RetResultCode.E13003);
    	}
    	
    	if (ex instanceof NotFoundDataException) {
    		NotFoundDataException e = (NotFoundDataException) ex;
    		return DefaultResult.buildFailedResult(e.getMsgCode(), e.getMessage());
    	}
    	
    	LoggerHelper.printLogErrorNotThrows(mLog, ex, null);
    	
		return DefaultResult.buildFailedResult(HttpStatus.INTERNAL_SERVER_ERROR.value(), ex.getMessage());
    }
    
    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    @ResponseBody
    public IBaseResult handleUnexpectedServerError1(MissingServletRequestParameterException ex) {
    	return DefaultResult.buildFailedResult(HttpStatus.BAD_REQUEST.value(), ex.getMessage());
    }

	/**
	 * 转换参数值
	 * @param value
	 */
	public String coventString(String value) {
		
		return StringUtils.isBlank(value) ? null : value;
	}
}